package com.swanclouds.redfish.systems;

import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.swanclouds.api.Apis;
import com.swanclouds.api.chassis.PCIeDeviceService;
import com.swanclouds.api.exceptions.ResourceNotFoundException;
import com.swanclouds.api.systems.*;
import com.swanclouds.core.transport.ClientConstants;
import com.swanclouds.model.common.ActionResponse;
import com.swanclouds.model.systems.ModifySystemReq;
import com.swanclouds.redfish.common.redfish.FruControl;
import com.swanclouds.redfish.common.redfish.ResetType;
import com.swanclouds.redfish.internal.BaseSystemService;
import com.swanclouds.redfish.systems.domain.Systems;

import java.util.Map;

/**
 * 系统资源
 *
 * @author 张立强
 *  
 */
public class SystemServiceImpl extends BaseSystemService implements SystemService {

    private static Map<String, Systems> map = null;

    static {
        if (map == null) {
            map = Maps.newConcurrentMap();
        }
    }

    /**
     * 查询系统资源实例
     * @return Systems
     */
    @Override
    public Systems get() {
        Systems execute = get(Systems.class, uri(ClientConstants.SYSTEMS_DETAIL, getSystemId())).execute();
        if (map.containsKey(getSystemId())) {
            return map.get(getSystemId());
        }
        map.put(getSystemId(),execute);
        return map.get(getSystemId());
    }

    /**
     * 修改指定系统资源属性
     *
     * @param modify 修改体
     * @return the Systems
     */
    @Override
    public Systems modify(ModifySystemReq modify) {
        return patch(Systems.class, uri(ClientConstants.SYSTEMS_DETAIL, getSystemId())).entity(modify).execute();
    }

    /**
     * 服务器开关机操作
     * @param resetType 操作
     * @return ActionResponse
     */
    @Override
    public ActionResponse ComputerSystemReset(ResetType resetType) {
        Preconditions.checkNotNull(resetType, "reset type is null");
        Systems systems = get();
        Systems.Actions action = systems.getAction();
        if (action.getOem() != null) {
            if (action.getComputerSystemReset() != null) {
                return postWithResponse(uri(action.getComputerSystemReset().getTarget())).entity(resetType).execute();
            }
        } else if (action.getTarget() != null) {
            return postWithResponse(uri(action.getTarget())).entity(resetType).execute();
        }
        return ActionResponse.actionFailed("服务器开关机失败",500);
    }

    /**
     * 华为 FRU上下电控制
     *
     * @param fruControl 操作
     * @return ActionResponse
     */
    @Override
    public ActionResponse ComputerSystemFruControl(FruControl fruControl) {
        Preconditions.checkNotNull(fruControl, "Fru Control is null");
        Systems.Actions action = get().getAction();
        if (action.getOem() != null && action.getComputerSystemReset() != null) {
            if (action.getOem().getHuawei() != null) {
                    return post(ActionResponse.class,uri(action.getComputerSystemReset().getTarget()))
                            .header(ClientConstants.HEADER_CONTENT_TYPE,ClientConstants.CONTENT_TYPE_JSON)
                            .entity(fruControl)
                            .execute();
            }
        }
        throw new ResourceNotFoundException("ComputerSystem.FruControl");
    }

    /**
     * 查询CPU集合资源服务
     * @return ProcessorService
     */
    @Override
    public ProcessorService Processor() {
        return Apis.get(ProcessorService.class);
    }

    /**
     * 查询内存集合资源服务
     * @return MemoryService
     */
    @Override
    public MemoryService Memory() {
        return Apis.get(MemoryService.class);
    }

    /**
     * 查询逻辑盘资源服务
     * @return StorageService
     */
    @Override
    public StorageService Storage() {
        return Apis.get(StorageService.class);
    }

    @Override
    public BiosService Bios() {
        return Apis.get(BiosService.class);
    }

    /**
     * @return 日志服务集合资源服务
     */
    @Override
    public LogServices Logs() {
        return Apis.get(LogServices.class);
    }

    /**
     * @return 以太网接口集合资源信息服务
     */
    @Override
    public EthernetInterfaceService EthernetInterface() {
        return Apis.get(EthernetInterfaceService.class);
    }

    /**
     * @return 网络接口集合资源服务
     */
    @Override
    public NetworkInterfaceService NetworkInterface() {
        return Apis.get(NetworkInterfaceService.class);
    }

    @Override
    public PCIeFunctionService PCIeFunction() {
        return Apis.get(PCIeFunctionService.class);
    }

    @Override
    public NetworkBondService Bond() {
        return Apis.get(NetworkBondService.class);
    }

    @Override
    public PCIeDeviceService PCIeDevice() {
        return Apis.get(PCIeDeviceService.class);
    }

    @Override
    public Boolean supportProcessorService() {
        if (map.containsKey(getSystemId())) {
            return map.get(getSystemId()).supportProcessorService();
        }
        return false;
    }

    @Override
    public Boolean supportMemoryService() {
        if (map.containsKey(getSystemId())) {
            return map.get(getSystemId()).supportMemoryService();
        }
        return get().supportMemoryService();
    }

    @Override
    public Boolean supportStorageService() {
        if (map.containsKey(getSystemId())) {
            Systems systems = map.get(getSystemId());
            return systems.supportStorageService();
        }
        return get().supportStorageService();
    }

    @Override
    public Boolean supportBiosService() {
        if (map.containsKey(getSystemId())) {
            Systems systems = map.get(getSystemId());
            return systems.supportBiosService();
        } else {
            return get().supportBiosService();
        }
    }

    @Override
    public Boolean supportEthernetInterfaceService() {
        if (map.containsKey(getSystemId())) {
            Systems systems = map.get(getSystemId());
            return systems.supportEthernetInterfaceService();
        }
        return get().supportEthernetInterfaceService();
    }

    @Override
    public Boolean supportNetworkInterfaceService() {
        return get().supportNetworkInterfaceService();
    }

    @Override
    public Boolean supportLogServices() {
        if (map.containsKey(getSystemId())) {
            return map.get(getSystemId()).supportLogServices();
        }
        return get().supportLogServices();
    }
}
